/*
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * This file is part of Harmattan SmashMiner OpenGL game application.
 * 
 * Harmattan SmashMiner OpenGL Example Application version 1.0.0
 *  
 * Latest update: 15.4.2011
 *
 * The Harmattan SmashMiner OpenGL example application demonstrates how to use 
 * the OpenGL ES in Harmattan devices.
 *
 * This example is provided as a starting point for 3rd party
 * developers (you) to ease the implementation of OpenGL based 
 * games. Ideas, parts of code or methodologies that this
 * example application uses can be freely used without restrictions.
 *
 * See file README.txt how to build and compile this example application
 * in the Harmattan SDK environment. 
 * 
 * See file INSTALL.txt to find out what is required to run this
 * application and how to install the application to the device or
 * alternatively in QEMU-emulator.
 *
 * The LICENSE.txt file explains the license this software is provided
 * with. A copy of the same license is included in this source file.
 * 
 */

/*
 * Copyright (C) 2011 by Nokia Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef PARTICLEDATA_H
#define PARTICLEDATA_H

#include "defines.h"

#include <QObject>
#include <QGLWidget>    // just for GLfloat...

/// \file particledata.h

/*! \enum ParticleType
 * Particle effect types
 */
enum ParticleType {
    /*! NULL particle effect (when initializing the  particle buffer, the particle type is set to
        \c ParticleType::ParticleTypeNULL.
    */
    ParticleTypeNULL = -1,
    /// Normal particle effect (rocket effect, explosion, etc.)
    ParticleTypeNormal = 0,
    /// Black hole particle effect
    ParticleTypeBlackHole = 1,
    /// Hyper jump particle effect
    ParticleTypeHyperJump = 2
};

/*! \struct Particle
 * Structure for storing OpenGL particle data.
 */
struct Particle
{
    /// Particle type (one of the values in enumeration \c ParticleType).
    ParticleType particleType;

    /// The game frame particle is born
    int startFrame;

    /// The game time particle is born
    GLfloat startTime;

    /*! Particle start position x-coordinate. Note: this is used for distance for 
     * blackhole particle
     */
    GLfloat startPosX;      // blachole-particle : distance

    /*! Particle start position x-coordinate. Note: this is used for radial velocity for 
     * blackhole particle
     */
    GLfloat startPosY;      // blachole-particle : radial velocity

    // no need to store the startPosZ value
    // since particle Z-coordinates never change.

    /// Particle start velocity (for x-axis)
    GLfloat startVelX;
    /// Particle start velocity (for y-axis)
    GLfloat startVelY;

    /*! Particle friction. Note: this is used for angle at start for black hole particle.
     *
     * The friction value does not change normally, but if a particle goes into a blackhole, then
     * it's friction value is set to zero.
     *
     * Friction value 1.0 = stop completely at end.
     */
    GLfloat startFrict;     // blachole-particle : angle at start

    /// Particle velocity (for x-axis)
    GLfloat velocityX;
    /// Particle velocity (for y-axis)
    GLfloat velocityY;
};

struct ParticleDataA
{
    GLfloat positionX;
    GLfloat positionY;
    GLfloat positionZ;
};

struct ParticleDataB
{
    GLfloat size;           // blackhole-particle : -radius (negative).
    GLfloat alpha;          // from 1.0 (opaque) to 0.0 (transparent).
    GLfloat friction;       // blackhole-particle : angle
};

class ParticleData : public QObject
{
    Q_OBJECT

public:

    friend class GameWidget;
    friend class GameEngine;

    explicit ParticleData(FPtype viewRangeX, FPtype viewRangeY, QObject *parent = 0);

    void addParticle(int, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
    void addParticleBlackHole(int, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
    void addParticleHyperJump(int, GLfloat, GLfloat, GLfloat, int);

    inline int writeIndex() { return particleWriteIndex; }

    inline QVector<Particle> &buffer() { return particleBuffer; }
    inline QVector<ParticleDataA> &bufferA() { return pBufferA; }
    inline QVector<ParticleDataB> &bufferB() { return pBufferB; }

signals:

public slots:

private:

    /// Buffer for storing particles (instances of \c Particle)
    QVector<Particle> particleBuffer;
    QVector<ParticleDataA> pBufferA;
    QVector<ParticleDataB> pBufferB;

    int particleWriteIndex;

    FPtype gameViewRangeX;
    FPtype gameViewRangeY;
};

#endif // PARTICLEDATA_H
